﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace PlutoStudio.Web.Mvc.Navigations
{
    public static class NavigationDiscover
    {
        private static List<ControllerNavigation> navigations;
        static NavigationDiscover()
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            var classes = new List<Type>();
            foreach (var item in assemblies)
            {
                classes.AddRange(item.GetTypes());
            }
            navigations = classes.Where(c => c.IsSubclassOf(typeof(ControllerBase)) && !c.IsAbstract).Select(c => new ReflectedControllerDescriptor(c)).Where(d => d.IsDefined(typeof(NavigationAttribute), false))
               .Select(d => new ControllerNavigation
               {
                   ControllerName = d.ControllerName,
                   Descriptor = d,
                   Attribute = d.GetFilterAttributes(true).Single(attr => attr is NavigationAttribute) as NavigationAttribute,
                   Actions = d.GetCanonicalActions().Where(a => a.IsDefined(typeof(NavigationAttribute), false)).Select(a => new ActionNavigation
                   {
                       ActionName = a.ActionName,
                       Attribute = a.GetFilterAttributes(true).Single(attr => attr is NavigationAttribute) as NavigationAttribute,
                       Descriptor = a,
                   }).OrderBy(a => a.Attribute.ItemOrder).ToList()
               }).OrderBy(d => d.Attribute.ItemOrder).ToList();
            navigations.ForEach(c => c.Actions.ForEach(a => a.Controller = c));
        }

        public static IEnumerable<ControllerNavigation> Navigations
        {
            get
            {
                return navigations;
            }
        }

        public static ControllerNavigation GetNavigation(string name)
        {
            return navigations.SingleOrDefault(n => n.ControllerName.ToLower() == name.ToLower());
        }
        public static ControllerNavigation GetNavigation(Type type)
        {
            return navigations.SingleOrDefault(n => n.Descriptor.ControllerType == type);
        }
    }
}
